package com.ken.work.mvc.listener;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Properties;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.apache.log4j.Logger;

import com.ken.work.mvc.DispatcherServlet;
import com.ken.work.mvc.SystemMapping;
import com.ken.work.mvc.annotation.MyController;
import com.ken.work.mvc.annotation.MyRequestMapping;
import com.ken.work.mvc.entity.ReflectObj;
/*
 * @author ken
 * 2017-02-17
 * 主要为了加载控制器
 */
public class MappingListener implements ServletContextListener {

	private static final Logger LOG = Logger.getLogger(DispatcherServlet.class);
	private static final String basePath="";
	private static String controllerPath ="";
	@Override
	public void contextInitialized(ServletContextEvent sce) {
		// TODO Auto-generated method stub
		controllerPath=sce.getServletContext().getInitParameter("controllerpath");
		initController();
	}

	@Override
	public void contextDestroyed(ServletContextEvent sce) {
		// TODO Auto-generated method stub
		SystemMapping.clear();
	}

	private void initController()
	{
		Properties pro = new Properties();
		ClassLoader classLoader = Thread.currentThread()
				.getContextClassLoader();
		System.out.println(classLoader.getClass().getPackage());
		try {
			System.out.println(classLoader.getResource("").getPath());
			String packagePath =classLoader.getResource("").getPath()+controllerPath.replace(".", "/");
			System.out.println(packagePath);
			// 遍历类和方法
			// 先遍历该路径下所有.class的文件名，再根据文件名构造ClassName路径，
			// 利用反射判断类是否存在，存在的话判断注释
			// 类上注释判断通过后，可以得到@MyRequestMapping注释里 路径字符串，
			// 再遍历方法，获取方法里的@MyRequestMapping注释字符串
			// 拼接字符串，作为key。class全路径和方法名 构造对象作为value
			File file = new File(packagePath);
			if (file.exists()) {
				File[] classFiles = file.listFiles();
				for (File file2 : classFiles) {
					if (!file2.isDirectory()) {
						String classUri = controllerPath
								+ "."
								+ file2.getName().substring(0,
										file2.getName().indexOf("."));
						System.out.println(classUri);
						Class cls = null;
						try {
							cls = Class.forName(classUri);
							Class cls1= Class.forName(classUri);
							System.out.println(cls.toString()+" "+cls1.toString());
						} catch (ClassNotFoundException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						String requesUri = null;
						if (cls == null)
							break;
						if (!cls.isAnnotationPresent(MyController.class)) {
							break;
						}
						if (cls.isAnnotationPresent(MyRequestMapping.class)) {
							@SuppressWarnings("unchecked")
							MyRequestMapping requestMapping = (MyRequestMapping) cls
									.getAnnotation(MyRequestMapping.class);
							requesUri = requestMapping.value();
						}
						String realRequesUri=requesUri;
						Method[] mts = cls.getMethods();
						for (Method method : mts) {
							if (!method.isAnnotationPresent(MyRequestMapping.class)) {
								continue;
							}
							MyRequestMapping requestMapping = (MyRequestMapping) method
									.getAnnotation(MyRequestMapping.class);
							realRequesUri = requesUri + requestMapping.value();
							ReflectObj aReflectObj=new ReflectObj(cls, method);
							SystemMapping.put(basePath+realRequesUri, aReflectObj);
							System.out.println(basePath+realRequesUri+"   "+classUri+" "+method.getName());
						}
					}
				}
			}

		} catch (Exception e) {
			LOG.error(e.getMessage());
		}
	}
	public static void main(String[] args) {
		new MappingListener().initController();
	}

}
